/**
 * 
 */
package com.davetrudes.jung.client.graphics.impl.canvas;

import com.davetrudes.jung.client.graphics.Color;
import com.davetrudes.jung.client.graphics.Component;
import com.davetrudes.jung.client.graphics.Dimension;
import com.davetrudes.jung.client.graphics.Font;
import com.davetrudes.jung.client.graphics.FontMetrics;
import com.davetrudes.jung.client.graphics.Graphics2D;
import com.davetrudes.jung.client.graphics.Paint;
import com.davetrudes.jung.client.graphics.Rectangle;
import com.davetrudes.jung.client.graphics.Shape;
import com.davetrudes.jung.client.graphics.Stroke;
import com.davetrudes.jung.client.graphics.component.Label;
import com.davetrudes.jung.client.graphics.exception.NotImplementedException;
import com.davetrudes.jung.client.graphics.geom.AffineTransform;
import com.davetrudes.jung.client.graphics.geom.GeneralPath;
import com.davetrudes.jung.client.graphics.geom.PathIterator;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Image;

/**
 * @author dave.trudes
 * 
 */
public class Canvas2DImplDefault extends Graphics2D {

	private Canvas canvas;
	private Context2d context;
	private AffineTransform transform = new AffineTransform();
	private Color foregroundColor = Color.BLACK;
	private Color backgroundColor = Color.WHITE;
	private Stroke stroke = new Stroke();
	private Font font = new Font();
	
	private double opacity = 1.0;
	private Paint paint;
	
	private int width, height;

	public Canvas2DImplDefault() {
		canvas = Canvas.createIfSupported();
		context = canvas.getContext2d();
		
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#clearRect(int, int, int, int)
	 */
	@Override
	public void clearRect(int x, int y, int width, int height){
		context.clearRect(x, y, width, height);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#clip(com.davetrudes.jung.client.graphics.Shape)
	 */
	@Override
	public void clip(Shape s) {
		throwEx("clip()", s.toString());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#clipRect(int, int, int, int)
	 */
	@Override
	public void clipRect(int x, int y, int width, int height) {
		throwEx("clipRect()", "[x:"+x+", y:"+y+", width:"+width+", height:"+height);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#copyArea(int, int, int, int, int, int)
	 */
	@Override
	public void copyArea(int x, int y, int width, int height, int dx, int dy) {
		throwEx("copyArea()", "...");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#dispose()
	 */
	@Override
	public void dispose() {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#draw(com.davetrudes.jung.client.graphics.Shape)
	 */
	@Override
	public void draw(Shape s) {
		System.out.println("draw shape: " + s);
		if (s instanceof GeneralPath) drawPath((GeneralPath) s);
		
	}
	
	private void drawPath(GeneralPath path){
		PathIterator it = path.getPathIterator(null);
		beginPath();
		while(!it.isDone()){
			double[] coords = new double[6];
			int seg = it.currentSegment(coords);
			switch(seg){
				case PathIterator.SEG_MOVETO:
					moveTo(coords[0], coords[1]);
					break;
				case PathIterator.SEG_LINETO:
					lineTo(coords[0], coords[1]);
					break;
				case PathIterator.SEG_QUADTO:
					quadraticCurveTo(coords[0], coords[1], coords[2], coords[3]);
					break;
				case PathIterator.SEG_CUBICTO:
					cubicCurveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
					break;
				case PathIterator.SEG_CLOSE:
					closePath();
				
			}
			it.next();
		}
	}

	
	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#cubicCurveTo(double, double, double, double, double, double)
	 */
	@Override
	public void cubicCurveTo(double cp1x, double cp1y, double cp2x,
			double cp2y, double x, double y) 
	{
		context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
	}

	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#closePath()
	 */
	@Override
	public void closePath() {
		context.closePath();
	}
	

	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#beginPath()
	 */
	@Override
	public void beginPath() {
		context.beginPath();
	}

	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#quadraticCurveTo(double, double, double, double)
	 */
	@Override
	public void quadraticCurveTo(double cpx, double cpy, double x, double y) {
		context.quadraticCurveTo(cpx, cpy, x, y);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#drawArc(int, int, int, int, int, int)
	 */
	@Override
	public void drawArc(int x, int y, int width, int height, int startAngle,
			int arcAngle) {
		

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#drawImage(com.google.gwt.user.client.ui.Image,
	 * com.davetrudes.jung.client.graphics.geom.AffineTransform)
	 */
	@Override
	public boolean drawImage(Image img, AffineTransform xform) {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#drawImage(com.google.gwt.user.client.ui.Image,
	 * int, int)
	 */
	@Override
	public boolean drawImage(Image img, int x, int y) {
		// TODO Auto-generated method stub
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#drawImage(com.google.gwt.user.client.ui.Image,
	 * int, int, com.davetrudes.jung.client.graphics.Color)
	 */
	@Override
	public boolean drawImage(Image img, int x, int y, Color bgcolor) {

		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#drawImage(com.google.gwt.user.client.ui.Image,
	 * int, int, int, int)
	 */
	@Override
	public boolean drawImage(Image img, int x, int y, int width, int height) {
		// TODO Auto-generated method stub
		return false;
	}

	
	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics#setHeight(int)
	 */
	@Override
	public void setHeight(int height) {
		canvas.setCoordinateSpaceHeight(height);
		this.height = height;
	}

	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics#setWidth(int)
	 */
	@Override
	public void setWidth(int width) {
		canvas.setCoordinateSpaceWidth(width);
		this.width = width;
	}

	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics#getSize()
	 */
	@Override
	public Dimension getSize() {
		return new Dimension(width, height);
	}

	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics#setSize(com.davetrudes.jung.client.graphics.Dimension)
	 */
	@Override
	public void setSize(Dimension size) {
		setWidth(size.width);
		setHeight(size.height);
	}

	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics#setSize(int, int)
	 */
	@Override
	public void setSize(int width, int height) {
		setWidth(width);
		setHeight(height);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#drawImage(com.google.gwt.user.client.ui.Image,
	 * int, int, int, int, com.davetrudes.jung.client.graphics.Color)
	 */
	@Override
	public boolean drawImage(Image img, int x, int y, int width, int height,
			Color bgcolor) {
		// TODO Auto-generated method stub
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#drawImage(com.google.gwt.user.client.ui.Image,
	 * int, int, int, int, int, int, int, int)
	 */
	@Override
	public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
			int sx1, int sy1, int sx2, int sy2) {
		// TODO Auto-generated method stub
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#drawImage(com.google.gwt.user.client.ui.Image,
	 * int, int, int, int, int, int, int, int, com.davetrudes.jung.client.graphics.Color)
	 */
	@Override
	public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
			int sx1, int sy1, int sx2, int sy2, Color bgcolor) {
		// TODO Auto-generated method stub
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#drawLine(int, int, int, int)
	 */
	@Override
	public void drawLine(int x1, int y1, int x2, int y2) {
		moveTo(x1, y1);
		lineTo(x2, y2);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#drawOval(int, int, int, int)
	 */
	@Override
	public void drawOval(int x, int y, int width, int height) {
		throwEx("drawOval", "x:"+x+" y:"+y+" width:"+width+" height:"+height);
	}

	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics#getOpacity()
	 */
	@Override
	public double getOpacity() {
		return opacity;
	}

	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics#setOpacity(double)
	 */
	@Override
	public void setOpacity(double opacity) {
		throw new NotImplementedException("setOpacity is not implemented");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#drawPolygon(int[], int[], int)
	 */
	@Override
	public void drawPolygon(int[] points, int[] points2, int points3) {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#drawPolyline(int[], int[], int)
	 */
	@Override
	public void drawPolyline(int[] points, int[] points2, int points3) {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#drawRoundRect(int, int, int, int, int, int)
	 */
	@Override
	public void drawRoundRect(int x, int y, int width, int height,
			int arcWidth, int arcHeight) {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#drawString(java.lang.String, float, float)
	 */
	@Override
	public void drawString(String s, float x, float y) {
		drawString(s, (int)x, (int)y);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#drawString(java.lang.String, int, int)
	 */
	@Override
	public void drawString(String str, int x, int y){
		context.fillText(str, x, y);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#fill()
	 */
	@Override
	public void fill(){
		context.fill();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#fill(com.davetrudes.jung.client.graphics.Shape)
	 */
	@Override
	public void fill(Shape s) {
		if (s instanceof GeneralPath){
			drawPath((GeneralPath) s);
			fill();
			return;
		}
		throwEx(getClass().getName()+"#fill()", s.toString());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#fillArc(int, int, int, int, int, int)
	 */
	@Override
	public void fillArc(int x, int y, int width, int height, int startAngle,
			int arcAngle) {
		throwEx("fillArc", "...");

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#fillOval(int, int, int, int)
	 */
	@Override
	public void fillOval(int x, int y, int width, int height) {
		throwEx("fillOval", "...");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#fillPolygon(int[], int[], int)
	 */
	@Override
	public void fillPolygon(int[] points, int[] points2, int points3) {
		throwEx("fillPolygon", "...");

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#fillRect(int, int, int, int)
	 */
	@Override
	public void fillRect(int x, int y, int width, int height) {
		context.fillRect(x, y, width, height);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#fillRoundRect(int, int, int, int, int, int)
	 */
	@Override
	public void fillRoundRect(int x, int y, int width, int height,
			int arcWidth, int arcHeight) {
		throwEx("fillRoundRect", "...");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#getBackground()
	 */
	@Override
	public Color getBackground(){
		return backgroundColor;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#getClip()
	 */
	@Override
	public Shape getClip() {
		// TODO Auto-generated method stub
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#getClipBounds()
	 */
	@Override
	public Rectangle getClipBounds() {

		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#getColor()
	 */
	@Override
	public Color getColor() {
		return foregroundColor ;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#getElement()
	 */
	@Override
	public Element getElement() {
		return canvas.getElement();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#getFont()
	 */
	@Override
	public Font getFont() {
		return font;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#getFontMetrics(com.davetrudes.jung.client.graphics.Font)
	 */
	@Override
	public FontMetrics getFontMetrics(Font f) {

		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#getPaint()
	 */
	@Override
	public Paint getPaint() {
		return paint;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#getStroke()
	 */
	@Override
	public Stroke getStroke() {
		return stroke;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#getTransform()
	 */
	@Override
	public AffineTransform getTransform() {
		return transform;
	}
	
	

	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#drawComponent(com.davetrudes.jung.client.graphics.Component)
	 */
	@Override
	public void drawComponent(Component component) {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#draw(com.davetrudes.jung.client.graphics.Component, int, int, int, int, boolean)
	 */
	@Override
	public void draw(Component component, int x, int y, int width, int height,
			boolean shouldValidate) {
		context.fillText(((Label) component).getText(), x, y); 
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#hit(com.davetrudes.jung.client.graphics.Rectangle, com.davetrudes.jung.client.graphics.Shape,
	 * boolean)
	 */
	@Override
	public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
		// TODO Auto-generated method stub
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#lineTo(double, double)
	 */
	@Override
	public void lineTo(double x, double y) {
		context.lineTo(x, y);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#moveTo(double, double)
	 */
	@Override
	public void moveTo(double x, double y) {
		context.moveTo(x, y);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#rotate(double)
	 */
	@Override
	public void rotate(double theta) {
		throwEx("rotate", "theta: " + theta);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#rotate(double, double, double)
	 */
	@Override
	public void rotate(double theta, double x, double y) {
		translate(x, y);
		rotate(theta);
		translate(-x, -y);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#scale(double, double)
	 */
	@Override
	public void scale(double sx, double sy) {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#setBackground(com.davetrudes.jung.client.graphics.Color)
	 */
	@Override
	public void setBackground(Color color) 
	{
		
		this.backgroundColor = color;
		throwEx("setBackgroundColor", "color");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#setClip(int, int, int, int)
	 */
	@Override
	public void setClip(int x, int y, int width, int height) {
		throwEx("setClip", "...");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#setClip(com.davetrudes.jung.client.graphics.Shape)
	 */
	@Override
	public void setClip(Shape clip) {
		throwEx("setClip", "Shape..");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#setColor(com.davetrudes.jung.client.graphics.Color)
	 */
	@Override
	public void setColor(Color c) {
		this.foregroundColor = c;
		setFillStyle(c.toHexString());
		
	}
	
	private void setFillStyle(String colorStr) {
		context.setFillStyle(colorStr);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#setFont(com.davetrudes.jung.client.graphics.Font)
	 */
	@Override
	public void setFont(Font font) {
		this.font = font;
		setFont(font.getStyle().name().toLowerCase(), String.valueOf(font.getSize()), font.getName().name().toLowerCase());
	}
	
	private void setFont(String a, String size, String name) {
		context.setFont("'" + a + " " + size + "px " + name + "'");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#setPaint(com.davetrudes.jung.client.graphics.Paint)
	 */
	@Override
	public void setPaint(Paint paint) {
		if (paint instanceof Color){
			Color c = (Color) paint;
			setFillStyle(c.toHexString());
		}
		this.paint = paint;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#setPaintMode()
	 */
	@Override
	public void setPaintMode() {
		throwEx("setPaintMode", "");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#setStroke(com.davetrudes.jung.client.graphics.Stroke)
	 */
	@Override
	public void setStroke(Stroke s) {
		this.stroke = s;
		setLineCap(s.getEndCap().getCssName());
		setLineJoin(s.getLineJoin().getCssName());
		setMiterLimit(s.getMiterLimit());
		setLineWidth(s.getLineWidth());
	}
	
	/**
	 * Sets the {@link Stroke#LineCap} natively.
	 * @param lineCap
	 */
	private void setLineCap(String lineCap) {
		context.setLineCap(lineCap);
	}
	
	/**
	 * Sets the {@link Stroke#LineJoin} natively.
	 * @param lineJoin
	 */
	private void setLineJoin(String lineJoin) {
		context.setLineJoin(lineJoin);
	}
	
	/**
	 * Sets the {@link Stroke#width} natively.
	 * @param width
	 */
	private void setLineWidth(double width) {
		context.setLineWidth(width);
	}
	
	/**
	 * Sets the {@link Stroke#miterlimit} natively.
	 * @param miterLimit
	 */
	private void setMiterLimit(double miterLimit) {
		context.setMiterLimit(miterLimit);
	}
	
	

	/* (non-Javadoc)
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#stroke()
	 */
	@Override
	public void stroke(){
		context.stroke();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#setTransform(com.davetrudes.jung.client.graphics.geom.AffineTransform)
	 */
	@Override
	public void setTransform(AffineTransform Tx) {
		this.transform = Tx;
		setTransform(Tx.m00, Tx.m01, Tx.m10, Tx.m11, Tx.m02, Tx.m12);
	}

	private void setTransform(double m11, double m12, double m21, double m22, double dx, double dy){
		context.setTransform(m11, m12, m21, m22, dx, dy);
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics#setXORMode(com.davetrudes.jung.client.graphics.Color)
	 */
	@Override
	public void setXORMode(Color c1) {
		throwEx("setXORMode", "");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#shear(double, double)
	 */
	@Override
	public void shear(double shx, double shy) {
		throwEx("shear", "");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#transform(com.davetrudes.jung.client.graphics.geom.AffineTransform)
	 */
	@Override
	public void transform(AffineTransform Tx) {
		setTransform(Tx.m00, Tx.m01, Tx.m10, Tx.m11, Tx.m02, Tx.m12);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#translate(double, double)
	 */
	@Override
	public void translate(double tx, double ty) {
		setTransform(1, 0, 0, 1, tx, ty);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.davetrudes.jung.client.graphics.Graphics2D#translate(int, int)
	 */
	@Override
	public void translate(int x, int y) {
		context.translate(x, y);
	}

	private void throwEx(String method, String details){
		throw new NotImplementedException(method+" -> "+details);
	}
	
}
